package com.github.cakin.shiro.chapter23.session.dao;

import com.github.cakin.shiro.chapter23.utils.SerializableUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.ValidatingSession;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.Serializable;
import java.util.List;

/**
 * @ClassName: MySessionDao
 * @Description: 自定义实现 SessionDAO，继承 CachingSessionDAO
 * @Date: 2020/5/22
 * @Author: cakin
 */
public class MySqlSessionDAO extends CachingSessionDAO {
    /**
     * jdbcTemplate
     */
    @Autowired
    private JdbcTemplate jdbcTemplate;

    /**
     * 功能描述：创建会话
     *
     * @param session 会话
     * @return Serializable 会话id
     * @author cakin
     * @date 2020/6/1
     * @description:
     */
    @Override
    protected Serializable doCreate( Session session ) {
        Serializable sessionId = generateSessionId(session);
        assignSessionId(session, sessionId);
        String sql = "insert into sessions(id, session) values(?,?)";
        jdbcTemplate.update(sql, sessionId, SerializableUtils.serialize(session));
        return session.getId();
    }

    /**
     * 功能描述：更新会话
     *
     * @param session 会话
     * @author cakin
     * @date 2020/6/1
     */
    @Override
    protected void doUpdate( Session session ) {
        if (session instanceof ValidatingSession && !((ValidatingSession) session).isValid()) {
            return; //如果会话过期/停止 没必要再更新了
        }
        String sql = "update sessions set session=? where id=?";
        jdbcTemplate.update(sql, SerializableUtils.serialize(session), session.getId());
    }

    /**
     * 功能描述：删除会话
     *
     * @param session
     * @author cakin
     * @date 2020/5/23
     */
    @Override
    protected void doDelete( Session session ) {
        String sql = "delete from sessions where id=?";
        jdbcTemplate.update(sql, session.getId());
    }

    /**
     * 功能描述：读取会话。
     *
     * @param sessionId SessionId
     * @return Session Session
     * @author cakin
     * @date 2020/5/23
     */
    @Override
    protected Session doReadSession( Serializable sessionId ) {
        String sql = "select session from sessions where id=?";
        List<String> sessionStrList = jdbcTemplate.queryForList(sql, String.class, sessionId);
        if (sessionStrList.size() == 0) {
            return null;
        }
        return SerializableUtils.deserialize(sessionStrList.get(0));
    }
}
